#ifndef TRIANGLE_H
#define TRIANGLE_H

#include "Point3D.h"
#include "Vector3D.h"
#include "../util/NTuple.h"
#include "MeshPoint.h"
namespace geom
{
	class Ray;
	class MeshPoint;
	/** Class that represents a triangle in a 3D space */
    class Triangle{
        public:
            /** Triangle vertex*/
            Point3D p1;
            /** Triangle vertex*/
            Point3D p2;
            /** Triangle vertex*/
            Point3D p3;
			/** Indicates if the normals have been created for a given vertex */
            bool normalsCreated[3];

			/** Returns the normal of the triangle, as the signed area for its
              forming vectors */
            Vector3D getNormal() const;

            /** Checks if this and the triangle t have any vertices in common */
            bool isAdyacentTo(const Triangle &t) const;

            /** Checks if p is one of this triangle's vertices */
            bool hasPoint(const Point3D &p) const;

            /** Gets one of the triangles vertices 
             @param pointNum Number of the point to get. Possible values: 0,1,2
             */
            Point3D getPoint(int pointNum) const;

            /** Sets a point as one of the triangles vertices
              @param p Point
              @param numPoint Index of the point to set. Possible values: 0,1,2*/
            void setPoint(const Point3D &p, int numPoint);
			
            /** Constructor. Creates a Triangle with vertices tp1,tp2,tp3 */
            Triangle(const Point3D &tp1, const Point3D &tp2, const Point3D &tp3);

			/** Constructor. Creates a Triangle with vertices tri[0], tri[1], tri[2] */
			Triangle(const util::Triplet<MeshPoint> tri);

            /** Default constructor. Creates a Triangle with all its vertices as (0,0,0)*/
            Triangle();
            
            /** Checks if the given Ray intersects with this triangle*/
            bool isIntersectedBy(const Ray &r) const;
			/** Gets the intersection point between a ray and this triangle (if it exists).
				\returns      -1 = triangle is degenerate (a segment or point)
				               0 = disjoint (no intersect)
				               1 = intersect in unique point I1
				               2 = are in the same plane
			*/
			int getRayIntersectionPoint(const Ray &R, Point3D* result )const;

			/** Gets the triangle area */
			float getArea() const
			{
				Vector3D v1 = p3 - p1;
				Vector3D v2 = p2 - p1;
				return v1.vectorProduct(v2).module() /2; 
			}
	};

}

#endif
